package com.lippeng.taohua.db.domain;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;

import com.lippeng.taohua.db.exception.TaoHuaDBException;
import com.lippeng.taohua.db.page.Page;
import com.lippeng.taohua.db.util.ResultBacker;
import com.lippeng.taohua.db.util.SqlBuilder;

/**
 * Here,I implement the IDmain interface in my way.
 * 
 * @author lippeng
 * 
 */
public class ImplementDomain implements IDomain {

	/**
	 * Dependency injection
	 */
	private Connection connection;
	private SqlBuilder sqlBuilder;
	private ResultBacker resultBacker;

	/**
	 * Constructor
	 * 
	 * @param domain
	 */
	public ImplementDomain(SuperDomain domain) {
		sqlBuilder = new SqlBuilder(domain);
		resultBacker = new ResultBacker(domain);
	}

	/**
	 * Methods
	 */

	@Override
	public Long count() {
		String sqlString = sqlBuilder.count();
		ResultSet resultSet = executeSelect(sqlString);
		if (null == resultSet) {
			throw new TaoHuaDBException("executeQuery Fail...");
		}
		Long value = resultBacker.count(resultSet);
		return value;
	}

	@Override
	public Boolean delete() {
		String sqlString = sqlBuilder.delete();
		Boolean value = executeUpdate(sqlString);
		return value;
	}

	@Override
	public List<? extends SuperDomain> executeQuery(String sqlString) {
		ResultSet resultSet = executeSelect(sqlString);
		if (null == resultSet) {
			throw new TaoHuaDBException("executeQuery Fail...");
		}
		List<SuperDomain> value = resultBacker.select(resultSet);
		return value;
	}

	/**
	 * Do query and return ResultSet
	 * 
	 * @param sqlString
	 * @return
	 */
	private ResultSet executeSelect(String sqlString) {
		ResultSet value = null;
		try {
			Statement statement = connection.createStatement();
			value = statement.executeQuery(sqlString);
		} catch (SQLException e) {
			e.printStackTrace();
			throw new TaoHuaDBException("executeQuery Fail...");
		}
		return value;
	}

	@Override
	public Boolean executeUpdate(String sqlString) {
		boolean value = false;
		int i = -1;
		try {
			Statement statement = connection.createStatement();
			i = statement.executeUpdate(sqlString);
		} catch (SQLException e) {
			e.printStackTrace();
			throw new TaoHuaDBException("executeUpdate Fail...");
		}
		if (i > 0) {
			value = true;
		}
		return value;
	}

	@Override
	public Boolean exist() {
		Boolean value = false;
		Long count = this.count();
		if (count > 0) {
			value = true;
		}
		return value;
	}

	@Override
	public Boolean insert() {
		String sqlString = sqlBuilder.insert();
		Boolean value = executeUpdate(sqlString);
		return value;
	}

	@Override
	public SuperDomain load() {
		String sqlString = sqlBuilder.load();
		ResultSet resultSet = executeSelect(sqlString);
		if (null == resultSet) {
			throw new TaoHuaDBException("executeQuery Fail...");
		}
		SuperDomain value = resultBacker.load(resultSet);
		return value;
	}

	@Override
	public List<SuperDomain> select() {
		String sqlString = sqlBuilder.select();
		ResultSet resultSet = executeSelect(sqlString);
		if (null == resultSet) {
			throw new TaoHuaDBException("executeQuery Fail...");
		}
		List<SuperDomain> value = resultBacker.select(resultSet);
		return value;
	}

	@Override
	public List<SuperDomain> selectEqual() {
		String sqlString = sqlBuilder.selectEqual();
		ResultSet resultSet = executeSelect(sqlString);
		if (null == resultSet) {
			throw new TaoHuaDBException("executeQuery Fail...");
		}
		List<SuperDomain> value = resultBacker.select(resultSet);
		return value;
	}

	@Override
	public List<SuperDomain> selectPageList(Page page) {
		String sqlString = sqlBuilder.selectPageList(page);
		ResultSet resultSet = executeSelect(sqlString);
		if (null == resultSet) {
			throw new TaoHuaDBException("executeQuery Fail...");
		}
		List<SuperDomain> value = resultBacker.select(resultSet);
		return value;
	}

	@Override
	public Boolean update() {
		String sqlString = sqlBuilder.update();
		Boolean value = executeUpdate(sqlString);
		return value;
	}

	@Override
	public Boolean updateNull() {
		String sqlString = sqlBuilder.updateNull();
		Boolean value = executeUpdate(sqlString);
		return value;
	}

	/**
	 * Getter and Setter
	 */

	public void setConnection(Connection connection) {
		this.connection = connection;
	}

	public Connection getConnection() {
		return connection;
	}

}
